home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / contrib / campbell / gplotlib.3 < prev    next >
Encoding:
Internet Message Format  |  1992-04-27  |  55.3 KB

  1. From jdc@naucse.cse.nau.edu Thu Mar  5 09:26:56 1992
  2. Return-Path: <jdc@naucse.cse.nau.edu>
  3. Received: from naucse.cse.nau.edu by ra-next.arc.nasa.gov (NeXT-1.0 (From Sendmail 5.52)/NeXT-1.0)
  4.     id AA10629; Thu, 5 Mar 92 09:26:37 PST
  5. Received: by naucse.cse.nau.edu (5.65c/1.5-nau)
  6.     id AA21527; Thu, 5 Mar 1992 10:32:21 -0700
  7. Message-Id: <199203051732.AA21527@naucse.cse.nau.edu>
  8. From: jdc@naucse.cse.nau.edu (John Campbell)
  9. Date: Thu, 5 Mar 1992 10:32:20 MST
  10. X-Mailer: Mail User's Shell (7.2.3 5/22/91)
  11. To: woo@ra-next.arc.nasa.gov
  12. Subject: gplotlib.shr2
  13. Status: R
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 2 (of 5)."
  22. # Contents:  bar.c cpr.1 cpr.c intro.doc
  23. # Wrapped by jdc@naucse.cse.nau.edu on Tue Feb 11 08:42:13 1992
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'bar.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'bar.c'\"
  27. else
  28. echo shar: Extracting \"'bar.c'\" \(7149 characters\)
  29. sed "s/^X//" >'bar.c' <<'END_OF_FILE'
  30. X#include <stdio.h>
  31. X#include "gsr.h"
  32. X
  33. X#define DEBUG
  34. X#undef DEBUG
  35. X
  36. Xchar *ylabel="", *xlabel="", *title="", *term=NULL;
  37. X
  38. X/* externs needed for getopt */
  39. Xextern char *optarg;
  40. Xextern int optind, opterr;  /* 0 opterr: print err message and return "?" */
  41. X
  42. X/*
  43. X   Do bar plots:
  44. X      bar [-x xlabel] [-y ylabel] [-t title] [-T term] [file [file2 ...]]
  45. X*/
  46. X
  47. Xmain(argc, argv)
  48. Xint argc;
  49. Xchar *argv[];
  50. X{
  51. X   FILE *in, *fopen();
  52. X   int c;
  53. X
  54. X/* Check options. */
  55. X   while ((c = getopt (argc, argv, "x:y:t:T:")) != EOF) {
  56. X      switch (c) {
  57. X      case 'x': 
  58. X         xlabel = optarg;
  59. X      break;
  60. X      case 'y': 
  61. X         ylabel = optarg;
  62. X      break;
  63. X      case 't': 
  64. X         title = optarg;
  65. X      break;
  66. X      case 'T': 
  67. X         term = optarg;
  68. X      break;
  69. X      case '?': 
  70. X      default:
  71. X         usage();
  72. X      }
  73. X   }
  74. X/* Find out what terminal we're on to compute the max number of points. */
  75. X   gt_init_terminal();
  76. X   if (term != NULL) 
  77. X      gt_change_term (term, -1);
  78. X   if (GTterm == 0) {
  79. X      fprintf (stderr, "Unknown terminal\n");
  80. X      exit(1);
  81. X   }
  82. X
  83. X   if (argc <= optind) {
  84. X      bar_graph(stdin);
  85. X      if (isatty(fileno(stdout)) && isatty(fileno(stdin)))
  86. X         getchar();
  87. X   }
  88. X   else {
  89. X      for (; optind < argc; ++optind) {
  90. X         if ((in = fopen (argv[optind], "r")) == NULL) {
  91. X            fprintf (stderr, "Can't open %s\n", argv[optind]);
  92. X            usage();
  93. X         }
  94. X         bar_graph(in);
  95. X         if (isatty(fileno(stdout)) && isatty(fileno(stdin)))
  96. X            getchar();
  97. X      }
  98. X   }
  99. X   gsr_reset_terminal();
  100. X}
  101. X
  102. X
  103. Xbar_graph(in)
  104. XFILE *in;
  105. X/* 
  106. X   Routine to make a bar graph out of a list of points.  The list of
  107. X   points come from the file named on the command line.
  108. X   Parameter:
  109. X
  110. X          in:  Pointer to file descriptor containing list of points.
  111. X*/
  112. X{
  113. X#define MAXBUF 255
  114. X   struct termentry *t = >term_tbl[GTterm];
  115. X   int *pnum, bar_w, x_loc, height, lcnt, max_points;
  116. X   int err, i, k, result, bar_cnt=0;
  117. X   float *pval, scale, pmax, pmin, dummy;
  118. X   char buf[MAXBUF];
  119. X
  120. X   max_points = (t->xmax - 4*t->h_char)/2;
  121. X
  122. X/* Read everything into an array of floats with room for 10 per line. */
  123. X   pval = (float *)malloc (10*sizeof(float)*max_points);
  124. X   pnum = (int *)malloc (sizeof(int )*max_points);
  125. X   pmin = VERYLARGE;
  126. X   pmax = -VERYLARGE;
  127. X   err = 0;
  128. X   for (lcnt=0; fgets (buf, MAXBUF, in) != NULL; ++lcnt) {
  129. X      result = sscanf(buf,"%f %f %f %f %f %f %f %f %f %f %f", 
  130. X        &pval[lcnt*10], &pval[lcnt*10+1], &pval[lcnt*10+2], &pval[lcnt*10+3], 
  131. X        &pval[lcnt*10+4], &pval[lcnt*10+5], &pval[lcnt*10+6], &pval[lcnt*10+7], 
  132. X        &pval[lcnt*10+8], &pval[lcnt*10+9], &dummy);
  133. X      if (result > 10) {
  134. X         err = 1;
  135. X         break;
  136. X      }
  137. X   /* Find the max and min of the overall array. */
  138. X      for (k = 0; k < result; ++k) {
  139. X         if (pval[lcnt*10+k] > pmax) pmax = pval[lcnt*10+k];
  140. X         if (pval[lcnt*10+k] < pmin) pmin = pval[lcnt*10+k];
  141. X      }
  142. X      pnum[lcnt] = result;  /* number of items on this line. */
  143. X      bar_cnt += result;
  144. X      if (bar_cnt > max_points) {
  145. X         err = 1;
  146. X         break;
  147. X      }
  148. X   }
  149. X   if (bar_cnt >= max_points) {
  150. X      fprintf (stderr, "Error on input: more than %d data elements\n", bar_cnt);
  151. X      exit(1);
  152. X   }
  153. X   if (err) {
  154. X      fprintf (stderr, "Error on input: line %d\n", lcnt);
  155. X      exit(1);
  156. X   }
  157. X
  158. X/* Now that we know max and min, we can initialize the plotting device. */
  159. X   gsr_init (stdout, 1.0, 100.0, pmin < 0.0 ? pmin : 0.0, pmax, 1, 1, 0, 0);
  160. X
  161. X/* Draw the bars represented by the array pval. */
  162. X   bar_plot (pval, pnum, lcnt, pmax, pmin);
  163. X}
  164. X
  165. X
  166. Xusage()
  167. X{
  168. X   fprintf (stderr, 
  169. X"usage: bar [-x xlabel] [-y ylabel] [-t title] [-T term] [file [file2 ...]]\n");
  170. X   fprintf (stderr, "List of terminals (on standard output):\n");
  171. X   gt_list_terms();
  172. X   exit(1);
  173. X}
  174. X
  175. X
  176. Xbar_plot (pval, pnum, lcnt, pmax, pmin)
  177. Xfloat pval[], pmax, pmin;
  178. Xint pnum[], lcnt;
  179. X/*
  180. X   Routine to draw the bars represented by values in array pval.
  181. X
  182. X   Parameters:
  183. X
  184. X         pval: array of groups of points to take as bar heights.
  185. X
  186. X         pnum: array of the number of points in the ith bar group.
  187. X
  188. X         lcnt: number of groups (10 at most per group) of bars to draw.
  189. X
  190. X         pcnt: number of points to draw. 
  191. X
  192. X         pmax: largest value in the pval array.
  193. X
  194. X         pmin: smallest value in the pval array.
  195. X*/
  196. X{
  197. X   int i, j, k, bar_cnt, zero, bar_h, bar_w, x_loc;
  198. X   struct termentry *t = >term_tbl[GTterm];
  199. X
  200. X/* Compute the width of the bar graph. */
  201. X   for (bar_cnt=i=0; i < lcnt; ++i)
  202. X      bar_cnt += pnum[i]+1;
  203. X
  204. X   bar_w = (GSRxright - GSRxleft)/bar_cnt;
  205. X
  206. X/* Compute start of first bar. */
  207. X   x_loc = (GSRxright - (bar_cnt-1)*bar_w)/2.0 + GSRxleft/2.0 + 0.5;
  208. X
  209. X   zero = gsr_map_y (0.0);
  210. X
  211. X#ifdef DEBUG
  212. X   for (i=0; i < lcnt; ++i) {
  213. X      fprintf (stderr, "%d: pval[%d] = ", pnum[i], i*10);
  214. X      for (k=0; k < pnum[i]; ++k) {
  215. X         fprintf (stderr, "%f ", pval[i*10+k]);
  216. X      }
  217. X      fprintf (stderr,"\n");
  218. X   }
  219. X   fprintf (stderr, "lcnt = %d\t", lcnt);
  220. X   fprintf (stderr, "pmax = %f\t", pmax);
  221. X   fprintf (stderr, "pmin = %f\n", pmin);
  222. X   fprintf (stderr, "zero = %d\t", zero);
  223. X   fprintf (stderr, "bar_cnt = %d\n", bar_cnt);
  224. X   fprintf (stderr, "bar_w = %d\n", bar_w);
  225. X   fprintf (stderr, "Hit return\n");
  226. X   (void )getchar();
  227. X#endif
  228. X
  229. X/* Put device into graphics mode. */
  230. X   gsr_graphics();
  231. X
  232. X/* Draw a box around the plot. */
  233. X   gsr_boundary();
  234. X
  235. X/* Draw tics for the y axis of the plot. */
  236. X   gsr_draw_tics (0, 0, 0, 1, 1, 1);
  237. X
  238. X/* Write the ylabel, xlabel, and title to the plot. */
  239. X   gsr_ylabel (ylabel);
  240. X   gsr_xlabel (xlabel);
  241. X   gsr_title  (title);
  242. X
  243. X/* Draw the zero line (we might want a different line type here). */
  244. X   if (pmin < 0.0)
  245. X      gsr_draw_axis (0.0, 0.0, 2);  /* Just y axis */
  246. X
  247. X/* Put the linetype back to something we expect. */
  248. X   gsr_line_point_type (0, 0);
  249. X
  250. X/* Draw lcnt bars of height pval[i] and width bar_w. */
  251. X   for (i = 0; i < lcnt; ++i) {
  252. X      for (k = 0; k < pnum[i]; ++k) {
  253. X         bar_h = gsr_map_y (pval[i*10+k]);
  254. X
  255. X#ifdef DEBUG
  256. X         fprintf (stderr, "bar_h = %d, linetype = %d\n", bar_h, k);
  257. X#endif
  258. X   
  259. X      /* Draw the bar's rectangle. */
  260. X         (*t->move)(x_loc,zero);
  261. X         (*t->vector)(x_loc, bar_h);
  262. X         (*t->vector)(x_loc+bar_w, bar_h);
  263. X         (*t->vector)(x_loc+bar_w, zero);
  264. X
  265. X      /* Shade in the rectangle just drawn. */
  266. X         if (k % 6 < 4) {
  267. X            for (j=0; j < bar_w; ++j) {
  268. X            /* Terminal drivers define points as unsigned int... */
  269. X               (*t->move)(x_loc+j,zero);
  270. X               if (j % (k % 4 + 1) == 0)
  271. X                  (*t->vector)(x_loc+j,bar_h);
  272. X            }
  273. X         }
  274. X         else {
  275. X            int lower, upper;
  276. X            if (zero < bar_h) {
  277. X               lower = zero;
  278. X               upper = bar_h;
  279. X            }
  280. X            else {
  281. X               lower = bar_h;
  282. X               upper = zero;
  283. X            }
  284. X            for (j=lower; j < upper; ++j) {
  285. X               if (j % (k % 3 + 1) == 0) {
  286. X                  (*t->move)(x_loc,j);
  287. X                  (*t->vector)(x_loc+bar_w,j);
  288. X               }
  289. X            }
  290. X         }
  291. X         x_loc += bar_w;
  292. X      }
  293. X      x_loc += bar_w;
  294. X   }
  295. X/* Back into text mode (to see the plot generated) */
  296. X   gsr_text();
  297. X}
  298. X
  299. X
  300. X
  301. END_OF_FILE
  302. if test 7149 -ne `wc -c <'bar.c'`; then
  303.     echo shar: \"'bar.c'\" unpacked with wrong size!
  304. fi
  305. # end of 'bar.c'
  306. fi
  307. if test -f 'cpr.1' -a "${1}" != "-c" ; then 
  308.   echo shar: Will not clobber existing file \"'cpr.1'\"
  309. else
  310. echo shar: Extracting \"'cpr.1'\" \(7847 characters\)
  311. sed "s/^X//" >'cpr.1' <<'END_OF_FILE'
  312. X.\" to produce the man page.
  313. X.\" troff -man -Tdumb cpr.tf | ddumb >cpr.p
  314. X.\"
  315. X.TH CPR 1L "14 Feb 1990"
  316. X.SH "NAME"
  317. Xcpr  \-  Code print (prepare source code for printing)
  318. X.SH "SYNOPSIS"
  319. X.B cpr
  320. X[\fB-CcFhiNnOsS\fR] [\fB-a\fI language\fR] [\fB-H\fI header\fR]
  321. X[\fB-l\fI pagelen\fR] [\fB-o\fI offset\fR] [\fB-P\fI printer\fR]
  322. X[\fB-p\fR[\fInum\fR]] [\fB-r\fR[\fInum\fR]] [\fB-T\fI title\fR]
  323. X[\fB-t\fI tabwidth\fR] [[\fB-f\fI flist\fR] | \fBfile...\fR]
  324. X.SH "DESCRIPTION"
  325. X.I cpr
  326. Xprints the files named in its argument list, preceding
  327. Xthe output with a table of contents.  (If there are not enough pages of
  328. Xoutput or enough table of content entries then printing the table of contents
  329. Xis normally suppressed).
  330. XIf a filename is preceded by
  331. X.B -f
  332. Xthen the specified file is assumed to contain a list of files to be
  333. Xprinted.  The filename "-" specifies standard input.
  334. XEach file printed is assumed to be source code in a "known" language
  335. Xand \fIcpr\fR searches
  336. Xfor the beginning and end of functions.
  337. XFunction names are added to
  338. Xthe table of contents and each function name in the output is bolded
  339. X(unless a printer type of DUMB is assumed).
  340. X.PP
  341. XNormally the suffix (.c, .y, .for, .f, .icn, .lsp, .l) of the file name
  342. Xdetermines which language is chosen
  343. Xin order to identify the beginning and end of
  344. Xfunctions.  This can be overridden with the -a option described below.
  345. XNote that Lisp programs are expected to end in .lsp or .l, but lex
  346. Xprograms also end in .l.  In this case, \fIcpr\fR reads a few lines of code
  347. Xlooking for % lex constructs or '(' lisp constructs to make its determination.
  348. XIf, when running in AUTO mode, \fIcpr\fR can't determine the language of the
  349. Xsource code it will issue a warning to stderr and process the file with
  350. Xlanguage set to NONE.
  351. X.PP
  352. XBy default, blank lines are inserted at the end of every function (or
  353. Xsubroutine).
  354. XThus functions and structure declarations are nicely
  355. Xisolated in the output. Occasionally, however, structure
  356. Xinitialization tables may produce lots of white space.
  357. XThe \fB\-r\fP[\fInum\fR] option changes the space left to the specified
  358. Xnumber of lines.  If 0 is specified, no space is left.
  359. X.PP
  360. XOriginally \fIcpr\fR assumed the printer could backspace--and
  361. Xdid bolding by using backspaces.  Most laser printers, and some
  362. Xbrain dead line printers, however, can not bold by backspacing.  Support for
  363. Xother printers was added using the environment variable CPRINTER.  Defining
  364. Xthe environment variable CPRINTER as DUMB, BACKSPACE, ANSI, LN03,
  365. XNECP5200, or POSTSCRIPT
  366. Xselects an appropriate printer initialization and bolding
  367. Xstyle.  ("DUMB" does no initialization or bolding, "BACKSPACE" uses ^H
  368. Xcharacters to achieve bolding, and POSTSCRIPT generates a file that can
  369. Xbe printed on a postscript printer.)
  370. X.SH "Options"
  371. X.TP
  372. X\fB\-C\fP\ \  requests \fIcpr\fR to ignore the heuristic that tests whether
  373. Xa table of contents is worth printing.  Normally \fIcpr\fR won't print
  374. Xtables of contents that are too small (too few routine
  375. Xnames) or reference too few pages.  \fB-C\fP overrides this heuristic and
  376. Xcauses the table to always be printed.
  377. X.TP
  378. X\fB\-c\fP\ \  requests \fIcpr\fR to produce only a table of contents, the
  379. Xfile contents themselves are not printed  (-c implies -C and overrides -F).
  380. X.TP
  381. X\fB\-F\fP\ \  requests \fIcpr\fR to produce only a listing of files, the
  382. Xtable of contents is not printed.
  383. X.TP
  384. X\fB\-h\fP\ \  produces a help message giving options and command syntax.
  385. X.TP
  386. X\fB\-i\fP\ \  forces \fBcpr\fP to ignore form-feeds in the original source.
  387. XBy default form-feeds found at the start of a line and terminated by the
  388. Xend of a line are treated as page breaks and inserted at the point they are
  389. Xencountered.
  390. X.TP
  391. X\fB\-N\fP\ \  forces page numbering to start with page 1 for each
  392. Xfile processed.
  393. X.TP
  394. X\fB\-n\fP\ \  indicates that output lines should be numbered with
  395. Xthe corresponding line number from the input file.
  396. X.TP
  397. X\fB\-O\fP\ \  assumes output is destined for a 2-up printer.  In this case
  398. Xeach file is started on an odd-numbered physical page and -T, and table
  399. Xof contents entries are accounted for when producing the output.
  400. X.TP
  401. X\fB\-s\fP\ \  indicates that the table of contents should be sorted
  402. Xby function name within each file.  By default the sort is case
  403. Xsensitive.
  404. X.TP
  405. X\fB\-S\fP\ \  do the sort just mentioned in a case-insensitive
  406. Xmanner. (\fB\-S\fP implies \fB\-sS\fP).
  407. X.TP
  408. X\fB\-a\fI lang\fR
  409. XSelect the language to use.  Default is AUTO, which
  410. Ximplies looking at the suffix (.y, .c, .f, .for, .l, .lsp) to determine
  411. Xwhich language is in use.  If no language is desired (no function names
  412. Xare highlighted) then \fB\-a NONE\fR may be used.  The current choices
  413. Xare \fIC\fR, \fIFORTRAN\fR, \fIICON\fR, and \fILISP\fR.
  414. XChoosing a language will apply that choice to all files regardless
  415. Xof the file suffix.
  416. X.TP
  417. X\fB\-H\fI header\fR
  418. XUse this \fIheader\fR instead of the
  419. Xfile name on the header line.
  420. X.TP
  421. X\fB\-l\fI pagelen\fP
  422. XUse this \fIpagelen\fR as the page length, rather
  423. Xthan the default 66 lines.
  424. X.TP
  425. X\fB\-o\fI offset\fP
  426. XInsert \fIoffset\fR number of blanks in front of
  427. Xeach line of source code.
  428. X.TP
  429. X\fB-P\fI\ printer\fR
  430. XOverride the default printer and the environment variable CPRINTER.
  431. XThe value of \fIprinter\fR can be any of the printers CPRINTER
  432. Xsupports (see above).  Adding a new
  433. Xprinter to the source code is not very hard and may be worth doing if
  434. Xthere is a special font or bolding method that would work better.
  435. X.TP
  436. X\fB-p\fR[\fInum\fR]
  437. XIndicate what proportion of the page in steps of 16
  438. Xshould be used for deciding if a new function needs a new page.
  439. XThat is \fB-p12\fR (the default) indicates that if a function starts
  440. Xwithin the top 12/16 (3/4) of the page then do it, otherwise put it
  441. Xon a new page.
  442. XThus the higher the number (up to 16) the closer to
  443. Xthe bottom of the page will functions be started.
  444. X.B -p0
  445. Xsays put each function on a new page, and is the default if no \fInum\fP
  446. Xis specified.
  447. X.TP
  448. X\fB-r\fR[\fInum\fR]
  449. XSpecify the number of blank lines to insert between
  450. Xfunctions (put out after seeing the function end).  \fB\-r0\fR leaves the
  451. Xoutput as it was in the original source code.  The default is 5 blank
  452. Xlines between functions.
  453. X.TP
  454. X\fB\-T\fI title\fP
  455. XCause \fIcpr\fR to print the contents of the file
  456. X\fItitle\fR before printing the table of contents.
  457. X.TP
  458. X\fB\-t\fI\ tabwidth\fR
  459. XCause output to be produced that will look correct with tabs expanded every
  460. X\fItabwidth\fR columns.  (The default is every 8 columns.)
  461. XAll output is processed with tabs expanded to spaces.
  462. X.TP
  463. X\fB\-f\fI flist\fR
  464. XObtain the list of files to print from the file \fIflist\fP rather
  465. Xthan from the command line.
  466. X.SH "FILES"
  467. X.nf
  468. X/tmp/cpr$$              \- temp files holding text
  469. X.fi
  470. X.SH "SEE ALSO"
  471. Xcb(1), cat(1), fold(1), num(1), pr(1), tgrind(l), vgrind(l)
  472. X.SH "DIAGNOSTICS"
  473. XVarious messages about being unable to open files or not finding the
  474. Xlanguage.
  475. XSelf explanatory.
  476. X.SH "BUGS"
  477. X\fICpr\fR may sometimes make a mistake in determining the language
  478. Xor identifying functions.  In 'C',
  479. Xfunctions declarations whose opening ( is not found on the same line
  480. Xas the function name will not be recognized.  Some forms of macros
  481. Xalso confuse the function recognition.  Also,
  482. X#ifdef's are not processed,
  483. Xso stuff inside them gets interpreted, which is especially annoying
  484. Xif the code has mismatched braces in these blocks.
  485. X.SH "AUTHOR(S)"
  486. X.IP "Paul Breslin" 2.0i
  487. Xoriginal, Human Computing Resources Corp.
  488. X.IP "Rick Wise" 2.0i
  489. Xsorting and use of standard input, CALCULON Corp.
  490. X.IP "David Wasley" 2.0i
  491. Xnumbering, times, etc., U. C. Berkeley.
  492. X.IP "Patrick Powell" 2.0i
  493. Xvariable number of lines between functions, University of Waterloo
  494. X.IP "Ian! D. Allen" 2.0i
  495. Xvariable tabs; redundant TOC suppression, University of Waterloo
  496. X.IP "Dennis Vadura" 2.0i
  497. Xmore options; better function recognition,
  498. XUniversity of Waterloo
  499. X.IP "John Campbell" 2.0i
  500. Xheader, offset, and support for various languages.
  501. END_OF_FILE
  502. if test 7847 -ne `wc -c <'cpr.1'`; then
  503.     echo shar: \"'cpr.1'\" unpacked with wrong size!
  504. fi
  505. # end of 'cpr.1'
  506. fi
  507. if test -f 'cpr.c' -a "${1}" != "-c" ; then 
  508.   echo shar: Will not clobber existing file \"'cpr.c'\"
  509. else
  510. echo shar: Extracting \"'cpr.c'\" \(27280 characters\)
  511. sed "s/^X//" >'cpr.c' <<'END_OF_FILE'
  512. X/*      if UNIX:        cc -O cpr.c
  513. X *      if MSDOS:       cc -O -DMSDOS cpr.c
  514. X *      if VMS:         define sys sys$library; cc cpr.c
  515. X *
  516. X *      This program prints the files named in its argument list, preceding
  517. X *      the output with a table of contents. Each file is assumed to be C
  518. X *      source code (but doesn't have to be) in that the program searches
  519. X *      for the beginning and end of functions. Function names are added to
  520. X *      the table of contents, provided the name starts at the beginning of
  521. X *      a line. The function name in the output is bolded.
  522. X *
  523. X *      By default blank space is inserted after every closing '}'
  524. X *      character. Thus functions and structure declarations are nicely
  525. X *      isolated in the output. The only drawback to this is that structure
  526. X *      initialization tables sometimes produce lots of white space.
  527. X *      The "-r" option removes this space, or changes it to the indicated
  528. X *      length.
  529. X *
  530. X *      The option "-l" indicates that the following argument is to be
  531. X *      the page length used for output (changing the page length hasn't been
  532. X *      tested much).
  533. X *
  534. X *      The option "-s" indicates that the table of contents should be sorted
  535. X *      by function name within each file.
  536. X *
  537. X *      The option "-n" indicates that output lines should be numbered with
  538. X *      the corresponding line number from the input file.
  539. X *
  540. X *      The option "-p" indicates what proportion of the page in steps of 16
  541. X *      should be used for deciding if a new function needs a new page.
  542. X *      That is -p12 (the default) indicates that if a function starts
  543. X *      within the top 12/16 (3/4) of the page then do it, otherwise put it
  544. X *      on a new page.  Thus the higher the number (upto 16) the closer to
  545. X *      the bottom of the page will functions be started. -p0 says put each
  546. X *      func on a new page.
  547. X *
  548. X *      Try it! You'll like it. (I call it cpr.c)
  549. X *
  550. X *      Written by:
  551. X *              Paul Breslin
  552. X *              Human Computing Resources Corp.
  553. X *              10 St. Mary St.
  554. X *              Toronto, Ontario
  555. X *              Canada, M4Y 1P9
  556. X *
  557. X *              -- ...!decvax!utcsrgv!hcr!phb
  558. X *
  559. X *      Sorting and standard input reading from:
  560. X *              Rick Wise, CALCULON Corp., Rockville, MD.
  561. X *              -- ...!decvax!harpo!seismo!rlgvax!cvl!umcp-cs!cal-unix!wise
  562. X *
  563. X *      File modified time,
  564. X *      numbered output,
  565. X *      optional white space,
  566. X *      improved function start tests from:
  567. X *              David Wasley, U.C.Berkeley
  568. X *              -- ...!ucbvax!topaz.dlw
  569. X *      Modified the -r to leave variable amounts of space
  570. X *              Patrick Powell, U. Waterloo
  571. X *
  572. X *      Changed handling of form feeds to start a new page AND print heading:
  573. X *              Terry Doner, U of Waterloo
  574. X *
  575. X *      Fixed up to locate more functions, and added -p option
  576. X *              Dennis Vadura, U of Waterloo
  577. X *              dvadura@watdragon.waterloo.edu (Dennis Vadura)
  578. X *
  579. X *              It will find things like  struct foo *f()...
  580. X *              but not things like     int
  581. X *                                      f
  582. X *                                      ()...
  583. X *              ie. the constraint is that the () must appear on the same line
  584. X *              as the function name.
  585. X *
  586. X *  Clean up a bit for 80286 machines (lints a bit cleaner, too)
  587. X *      Dan Frank, Prairie Computing
  588. X *
  589. X *  Fixed a whole bunch of stuff and added lots of new flags.
  590. X *      -S       sort and be case insensitive.
  591. X *      -N       start numbering pages at 1 for each new file
  592. X *      -T title cat the file title before the table of contents.
  593. X *      -C       print only the table of contents
  594. X *      -c       only try to look for function names in files whose suffix ends
  595. X *               in .c
  596. X *      -f file  to handle file containing list of files to print. (for MSDOS)
  597. X *      Dennis Vadura
  598. X *
  599. X *  Added VMS and Language support, -h, -o options, reorganized bolding, and
  600. X *  shortened long names (so page numbers aren't lost).  Also put in getopt().
  601. X *  Oh yeah, expanded tabs (which wasn't what -t originally meant).
  602. X *      -h str   String to put at the top of each page instead of file name.
  603. X *      -o off   Number of spaces to put in front of each line of code.
  604. X *      -a lang  Assume the following language.  Default is AUTO (use file
  605. X *               name suffix to guess language).  NONE is allowed to mean
  606. X *               don't look for function names at all.
  607. X *      -cC      Dennis Vadura's -c option is thus generalized and removed.
  608. X *               -C becomes -c (VMS requires quotes around uppercase options,
  609. X *               so where possible use lower case...)  New -C added to override
  610. X *               supression of table of contents for small output jobs.  (NONE
  611. X *               means no table of content entries, hence none printed.)
  612. X *
  613. X *               Adding a language involves (at least):
  614. X *               1) Add to enum langs.
  615. X *               2) Add recognition of language keyword (FORTRAN) to getopt().
  616. X *               3) Add reference in man page and in Usage() function.
  617. X *               4) Add recognition to Scan() for end of functions.
  618. X *               5) Build a LooksLikeXXXX() to call inside LooksLikeFunction().
  619. X *               6) Add suffix recognition to WhichLanguage().
  620. X *               Then search everywhere for Language and see if you've missed
  621. X *               anything; if so edit this comment (smile).
  622. X *
  623. X *      John Campbell (...!arizona!naucse!jdc  or  CAMPBELL@NAUVAX)
  624. X *
  625. X *  Dennis Vadura:
  626. X *    Added a few options, -i, to ignore form-feed chars in original
  627. X *    source, -O to force output for two-up printing (this option
  628. X *    affects both table of contents and the file listing output and
  629. X *    handles the -T option correctly), added -F to print only file
  630. X *    listings.
  631. X *
  632. X *    renamed John Campbell's -h str to -H str so that -h can be used as
  633. X *    help (ie. the -? gets you in trouble in most shells and you have to
  634. X *    escape it etc.)
  635. X *
  636. X *    Cleaned up printing of help message.
  637. X *
  638. X *    Oh, what the hell, took the a2ps.c postscript converter and added the
  639. X *    capability to produce a postscript output file.  Seems Really nice,
  640. X *    might need a bit of tweeking but hey, I don't have hours to spend.
  641. X *    It's good enough for me :-)
  642. X *
  643. X *    To do this I hacked the code quite a bit, re-organized some functions
  644. X *    put in new ones, and made all output go through a common set of
  645. X *    routines.  I also changed cpr's output format to match that of the
  646. X *    postscript code.
  647. X *
  648. X *    I took the a2ps postscript code and embeded it into cpr, I prefered
  649. X *    this over keeping it as an included separate file, in an effort to
  650. X *    keep cpr self contained.
  651. X *
  652. X *    Bumped the version # to 2.5.
  653. X */
  654. Xchar *version = "2.5"; /* Just a guess--never had one before. */
  655. X
  656. X#include <sys/types.h>
  657. X#include <sys/stat.h>
  658. X#include <stdio.h>
  659. X#include <ctype.h>
  660. X#include <signal.h>
  661. X#include <string.h>
  662. X#ifdef __TURBOC__
  663. X#define MSDOS 1
  664. X#endif
  665. X#ifndef VMS
  666. Xextern int errno; /* system error number */
  667. Xextern char *sys_errlist[]; /* error message */
  668. X#define CANT_OPEN(p1) \
  669. X   fprintf(stderr,"%s: Can't open file '%s': %s\n", \
  670. X           ProgName, p1, sys_errlist[errno] )
  671. X#else
  672. X#include <perror.h>
  673. X#define CANT_OPEN(p1) \
  674. X   if (errno == EVMSERR) {\
  675. X      fprintf (stderr, "Can't open %s\n", p1);\
  676. X      LIB$STOP (vaxc$errno);\
  677. X   }\
  678. X   fprintf(stderr,"%s: Can't open file '%s': %s\n",\
  679. X           ProgName, p1, sys_errlist[errno] )
  680. X#endif
  681. X#if MSDOS || VMS
  682. X#include "getopt.c"
  683. X#endif
  684. X
  685. Xextern char *malloc() ; /* important for 8086-like systems */
  686. X
  687. X#define FALSE        0
  688. X#define TRUE        1
  689. X
  690. X#define TOC_SIZE        4096
  691. X#define MAXLINE          256
  692. X
  693. X#define NEWFILE         1
  694. X#define NEWFUNCTION     2
  695. X
  696. X#define SMALLC          8   /* Too few contents for a table of contents. */
  697. X#define SMALLP         10   /* Too few pages for a table of contents. */
  698. X
  699. XFILE *File, *FList = NULL;
  700. X
  701. Xint Braces; /* Keeps track of brace depth       */
  702. Xint LineNumber; /* Count output lines           */
  703. Xint PageNumber = 1; /* You figure this one out  */
  704. Xint ActualPageCount = 0; /* Actual number of pages printed */
  705. Xint PageLength = 66; /* -l <len> Normal paper length    */
  706. Xint PagePart = 12; /* Decision on paging for new fn*/
  707. Xint PageEnd; /* Accounts for space at bottom    */
  708. Xint SawFunction;
  709. Xint InComment;
  710. Xint InString;
  711. Xint ResetPage=0;
  712. Xint ContentsOnly=0;
  713. Xint FilesOnly=0;
  714. Xint AlwaysContents=0;
  715. Xint CaseInsensitive=0;
  716. Xint StartOdd=0;
  717. Xint IgnoreFF=0;
  718. X
  719. Xlong FileLineNumber; /* Input file line number  */
  720. X
  721. Xchar *TitleFile = NULL;
  722. Xchar *ProgName;
  723. Xchar Today[30];
  724. Xchar *Name; /* Current file name                */
  725. Xchar *Header = NULL;  /* User's header (-h "header") */
  726. Xchar *Title  = NULL;
  727. X
  728. Xchar *FileDate; /* Last modified time of file        */
  729. Xchar FunctionName[MAXLINE+1];
  730. X
  731. Xchar SortFlag; /* -s == sort table of contents  */
  732. Xchar NumberFlag; /* -n == output line numbers   */
  733. Xint OffsetValue = 0; /* -o <number> Offset each line (of code) N spaces */
  734. Xint Space_to_leave = 5; /* -r<number> space to leave    */
  735. Xint TabWidth = 8; /* -t <number> width of tabs  */
  736. X
  737. X/* Language types */
  738. Xenum langs {NONE, AUTO, C, FORTRAN, ICON, LISP}
  739. X   Language = AUTO;
  740. X/*
  741. X   Printer types (Would you believe I have to support a printer that can't
  742. X   backspace?  Geesh!)
  743. X*/
  744. X#define DUMB       0
  745. X#define BACKSPACE  1       /* Probably most reasonable default. */
  746. X#define ANSI       2       /* Just uses ansi escape sequences to bold */
  747. X#define LN03       3       /* For now same as ANSI--later smaller print! */
  748. X#define NECP5200   4       /* NEC 24 pin printer--in HS mode. */
  749. X#define POSTSCRIPT 5       /* print on a postscript printer */
  750. Xint Printer = BACKSPACE;   /* Choose your default. */
  751. X
  752. Xextern char *optarg;
  753. Xextern int optind, opterr;
  754. X
  755. Xstatic char *Toc[TOC_SIZE];
  756. Xstatic int TocPages[TOC_SIZE];
  757. Xstatic int TocCount;
  758. X
  759. X
  760. X#ifdef VMS
  761. X#include <errno.h>  /* Watch out for EVMSERR (special 65535 errno) */
  762. X#define unlink delete
  763. X#define toupper _toupper  /* Faster to use macro version. */
  764. X/*
  765. X   Local (NAU) support for redirection, other VMS sites can leave this out,
  766. X   but then they can't use wild cards (*.c), or redirection (>cpr.out).
  767. X   If you are a VMS site and want this contact CAMPBELL@NAUVAX.bitnet.
  768. X*/
  769. X#include "nau_utils:redexp.vms"
  770. X#endif
  771. Xmain(argc, argv)
  772. Xchar **argv;
  773. X{
  774. X   register int i;
  775. X   char *ctime();
  776. X   char *pname=NULL;
  777. X   char *s;
  778. X   time_t thetime, time();
  779. X   int c;
  780. X   enum langs start_lang, WhichLanguage();
  781. X
  782. X   FileDate = (char *)malloc(100);
  783. X   ProgName = argv[0];
  784. X   thetime = time((time_t *)0);
  785. X   strcpy(Today,ctime(&thetime));
  786. X   if( (s = strchr(Today,'\n')) != NULL ) *s = '\0';
  787. X
  788. X/* Parse options. */
  789. X   while ((c = getopt (argc, argv, "cCFhisSnNOa:f:H:t:T:l:o:r:p:P:")) != EOF) {
  790. X      switch (c) {
  791. X      case 'a':                    /* Assume a language ('C', FORTRAN,...) */
  792. X         c = *optarg;
  793. X         switch (c) {
  794. X         case 'C':
  795. X         case 'c':
  796. X            Language = C;
  797. X         break;
  798. X         case 'F':
  799. X         case 'f':
  800. X            Language = FORTRAN;
  801. X         break;
  802. X         case 'I':
  803. X         case 'i':
  804. X            Language = ICON;
  805. X         break;
  806. X         case 'L':
  807. X         case 'l':
  808. X            Language = LISP;
  809. X         break;
  810. X         case 'N':
  811. X         case 'n':
  812. X            Language = NONE;
  813. X         break;
  814. X         case 'A':
  815. X         case 'a':
  816. X            Language = AUTO;
  817. X         break;
  818. X         default:
  819. X            fprintf (stderr, "Unknown or unsupported language\n");
  820. X        exit(1);
  821. X         }
  822. X         break;
  823. X
  824. X      case 'F':
  825. X     ++FilesOnly;
  826. X     break;
  827. X
  828. X      case 'O':
  829. X     ++StartOdd;
  830. X     break;
  831. X
  832. X      case 'i':
  833. X     ++IgnoreFF;
  834. X     break;
  835. X
  836. X      case 'f':
  837. X         if (*optarg == '-') {
  838. X            FList = stdin;
  839. X         }
  840. X         else if ((FList = fopen (optarg, "r")) == NULL) {
  841. X            fprintf (stderr, "Can't open file names list %s\n", optarg);
  842. X        exit(1);
  843. X         }
  844. X         break;
  845. X      case 'H':       /* User's header */
  846. X         Header = optarg;
  847. X         break;
  848. X
  849. X      case 't':
  850. X         TabWidth = atoi(optarg);
  851. X         if( TabWidth < 0 )
  852. X            TabWidth = 0;
  853. X         break;
  854. X
  855. X      case 'T':
  856. X         TitleFile = optarg;
  857. X         break;
  858. X
  859. X      case 'l':
  860. X         PageLength = atoi(optarg);
  861. X         if( PageLength < 10) PageLength = 10;
  862. X         break;
  863. X
  864. X      case 'S':
  865. X         ++CaseInsensitive;
  866. X      case 's':
  867. X         ++SortFlag;
  868. X         break;
  869. X
  870. X      case 'C':
  871. X         ++AlwaysContents;
  872. X         break;
  873. X
  874. X      case 'c':
  875. X         ++ContentsOnly;
  876. X         break;
  877. X
  878. X      case 'n':
  879. X         ++NumberFlag;
  880. X         break;
  881. X
  882. X      case 'N':
  883. X         ++ResetPage;
  884. X         break;
  885. X
  886. X      case 'o':            /* Offset code by <number> */
  887. X         OffsetValue = atoi(optarg);
  888. X         if (OffsetValue <= 0) {
  889. X            fprintf (stderr, "Offset must be a positive integer only\n");
  890. X        exit(1);
  891. X         }
  892. X         if (OffsetValue > 32) {
  893. X            fprintf (stderr, "Offset must be less than 32\n");
  894. X        exit(1);
  895. X         }
  896. X         break;
  897. X
  898. X      case 'r':
  899. X      /* It's ok to have a '0' from the "?" here... */
  900. X         Space_to_leave = atoi(optarg);
  901. X         break;
  902. X
  903. X      case 'P':
  904. X         pname = optarg;  /* Override printer default or CPRINTER environ */
  905. X         break;
  906. X
  907. X      case 'p':
  908. X         PagePart = atoi(optarg);
  909. X         PagePart = PagePart <= 16 ? PagePart : 16;
  910. X         break;
  911. X
  912. X      case 'h':
  913. X      default:
  914. X         Usage();
  915. X         break;
  916. X      }
  917. X   }
  918. X
  919. X   start_lang = Language;
  920. X
  921. X   Init (pname);
  922. X   StartTempFile();
  923. X
  924. X   i = optind;
  925. X
  926. X   if( FList == NULL && i == argc )
  927. X   { /* no file names */
  928. X      File = stdin;
  929. X      Name = "Standard Input";
  930. X      if (start_lang == AUTO) Language = C;
  931. X      List();
  932. X   }
  933. X
  934. X   if( FList != NULL)
  935. X   {
  936. X      char b[1024];
  937. X
  938. X      while( fgets(b, 1024, FList) != NULL )
  939. X      {
  940. X         if( strlen(b) ) b[strlen(b)-1]=0;
  941. X
  942. X         if( strcmp(b, "-") != 0 )
  943. X         {
  944. X            if( (File = fopen( Name = b, "r" )) == NULL )
  945. X            {
  946. X               CANT_OPEN (Name);
  947. X               continue;
  948. X            }
  949. X            if (start_lang == AUTO) {
  950. X               Language = WhichLanguage (Name);
  951. X            }
  952. X         }
  953. X         else {
  954. X            Name = "Standard Input";
  955. X            if (start_lang == AUTO) Language = C;
  956. X            File = stdin;
  957. X         }
  958. X
  959. X         List();
  960. X         if( File != stdin ) fclose(File);
  961. X      }
  962. X   }
  963. X   for(; i < argc; ++i )
  964. X   {
  965. X      if( strcmp(argv[i], "-") == 0 )
  966. X      {
  967. X         File = stdin;
  968. X         Name = "Standard Input";
  969. X         if (start_lang == AUTO) Language = C;
  970. X         List();
  971. X      }
  972. X      else {
  973. X         if( (File = fopen( Name = argv[i], "r" )) == NULL )
  974. X         {
  975. X            CANT_OPEN (Name);
  976. X            continue;
  977. X         }
  978. X         if (start_lang == AUTO) {
  979. X            Language = WhichLanguage (Name);
  980. X         }
  981. X         List();
  982. X         if( File != stdin ) fclose(File);
  983. X      }
  984. X   }
  985. X
  986. X   if( PageNumber > 1 || LineNumber > 0 ) BlankPage();
  987. X   if( StartOdd && ((ActualPageCount % 2) != 0) ) BlankPage();
  988. X
  989. X   Fini();
  990. X   EndTempFile();
  991. X
  992. X   if( Printer == POSTSCRIPT ) DumpPostscriptHeader();
  993. X   DumpTableOfContents();
  994. X   DumpTempFiles();
  995. X   Done();
  996. X}
  997. X
  998. XUsage()
  999. X{
  1000. X   char buf[132];
  1001. X   char *p;
  1002. X   sprintf( buf, "Usage: %s ", ProgName );
  1003. X
  1004. X   printf("%s[-CcFhiNnOsS] [-a language] [-H header] [-l pagelen]\n", buf);
  1005. X   for(p=buf; *p; *p++ = ' ' );
  1006. X   printf("%s[-o offset] [-P printer] [-p[num]] [-r[num]] [-T title]\n", buf);
  1007. X   printf("%s[-t tabwidth] [[-f flist] | file...]\n\n", buf );
  1008. X
  1009. X   puts("OPTIONS: (first group can be combined)");
  1010. X   puts("   -C   - Force output of table of contents" );
  1011. X   puts("   -c   - Print only table of contents (implies -C, overrides -F)" );
  1012. X   puts("   -F   - Print only file contents" );
  1013. X   puts("   -h   - Provide help message (you're reading it)" );
  1014. X   puts("   -i   - Ignore form-feeds in original source");
  1015. X   puts("   -N   - Number pages of each file starting at page #1" );
  1016. X   puts("   -n   - Number output lines of each file" );
  1017. X   puts("   -O   - Force new files to start at an odd numbered actual page" );
  1018. X   puts("   -s   - Sort TOC by function name within each file" );
  1019. X   puts("   -S   - Same sort as -s, but ignore case\n" );
  1020. X
  1021. X   puts("   -a language - select language class" );
  1022. X   puts("   -H header   - specify personal heading" );
  1023. X   puts("   -l pagelen  - define new pagelength" );
  1024. X   puts("   -o offset   - set offset from left of page" );
  1025. X   puts("   -P print    - select printer class" );
  1026. X   puts("   -p[num]     - control function placement on page" );
  1027. X   puts("   -r[num]     - control function spacing on page" );
  1028. X   puts("   -T title    - print a title from file 'title'" );
  1029. X   puts("   -t tabwidth - set tabwidth" );
  1030. X   puts("   -f flist    - read 'flist' for list of files to print\n" );
  1031. X
  1032. X   puts("Language choices are:  C, FORTRAN, ICON, and LISP" );
  1033. X   puts("Supported printers:    DUMB, BACKSPACE, ANSI, LN03, NECP5200, and POSTSCRIPT");
  1034. X   exit(1);
  1035. X}
  1036. X
  1037. Xint SaveOut;
  1038. Xchar *TempName;
  1039. Xchar *Temp2Name;
  1040. X
  1041. XStartTempFile()
  1042. X{
  1043. X   int Done();
  1044. X   extern char *mktemp();
  1045. X
  1046. X   CatchSignalsPlease(Done);
  1047. X
  1048. X   SaveOut = dup(1);
  1049. X#if MSDOS | VMS
  1050. X   TempName = "cpr0001.tmp";
  1051. X#else
  1052. X   TempName = mktemp("/tmp/cprXXXXXX");
  1053. X#endif
  1054. X   if( freopen(TempName, "w", stdout) == NULL )
  1055. X   {
  1056. X      CANT_OPEN (TempName);
  1057. X      exit(1);
  1058. X   }
  1059. X}
  1060. X
  1061. XEndTempFile()
  1062. X{
  1063. X#if MSDOS | VMS
  1064. X   Temp2Name = "cpr0002.tmp";
  1065. X#else
  1066. X   Temp2Name = mktemp("/tmp/cprXXXXXX");
  1067. X#endif
  1068. X   if( freopen(Temp2Name, "w", stdout) == NULL )
  1069. X   {
  1070. X      CANT_OPEN (Temp2Name);
  1071. X      exit(1);
  1072. X   }
  1073. X}
  1074. X
  1075. XDumpTempFiles()
  1076. X{
  1077. X#if (MSDOS | VMS)
  1078. X   FILE *f;
  1079. X   char b[256];
  1080. X#endif
  1081. X   register int pid, w;
  1082. X
  1083. X   fclose(stdout);
  1084. X
  1085. X#if !(MSDOS || VMS)
  1086. X   dup(SaveOut);
  1087. X   while( (pid = fork()) < 0 ) sleep(1);
  1088. X   if( pid )
  1089. X      while ((w = wait((int *)0)) != pid && w != -1);
  1090. X   else
  1091. X      {
  1092. X      CatchSignalsPlease(SIG_DFL);
  1093. X
  1094. X      if( ContentsOnly )
  1095. X         execl( "/bin/cat", "cat", Temp2Name, (char *)0 );
  1096. X      else {
  1097. X      /*
  1098. X         Ok, use a heuristic to see if it is worth putting out the
  1099. X         table of contents.  They seem useless and annoying when cpr
  1100. X         is just printing a small job.  Heuristic: more than 10 entries
  1101. X         in the table of contents AND more than 8 pages of output.
  1102. X      */
  1103. X         if( !FilesOnly &&  (AlwaysContents ||
  1104. X                      (TocCount > SMALLC && TocPages[TocCount-1] > SMALLP)))
  1105. X           execl( "/bin/cat", "cat", Temp2Name, TempName, (char *)0 );
  1106. X         else
  1107. X            execl( "/bin/cat", "cat", TempName, (char *)0 );
  1108. X      }
  1109. X      fprintf(stderr, "%s: exec of /bin/cat failed: %s\n", ProgName,
  1110. X      sys_errlist[errno]);
  1111. X      exit(1);
  1112. X   }
  1113. X#else
  1114. X   CatchSignalsPlease(SIG_DFL);
  1115. X   /*
  1116. X      Use a heuristic to see if it is worth putting out the table of contents.
  1117. X      They seem useless and annoying when cpr is printing a small job.
  1118. X      Heuristic: > 10 entries in the table of contents or > 8 pages of output.
  1119. X   */
  1120. X   if( !FilesOnly && (AlwaysContents || (TocCount > SMALLC &&
  1121. X TocPages[TocCount-1] > SMALLP))) {
  1122. X      if( (f=fopen(Temp2Name,"r")) == NULL ) {
  1123. X         CANT_OPEN (Temp2Name);
  1124. X      }
  1125. X      else
  1126. X      {
  1127. X         while( fgets(b, MAXLINE, f) != NULL )
  1128. X            write(SaveOut,b,strlen(b));
  1129. X
  1130. X         fclose(f);
  1131. X      }
  1132. X   }
  1133. X   if( !ContentsOnly )
  1134. X      if( (f=fopen(TempName,"r")) == NULL ) {
  1135. X      CANT_OPEN (TempName);
  1136. X      }
  1137. X      else
  1138. X      {
  1139. X         while( fgets(b, MAXLINE, f) != NULL )
  1140. X            write(SaveOut,b,strlen(b));
  1141. X
  1142. X         fclose(f);
  1143. X      }
  1144. X#endif
  1145. X}
  1146. X
  1147. XDone()
  1148. X{
  1149. X   CatchSignalsPlease(SIG_DFL);
  1150. X
  1151. X   fclose( stdout );
  1152. X   if( TempName ) unlink( TempName );
  1153. X   if( Temp2Name ) unlink( Temp2Name );
  1154. X
  1155. X   exit(0);
  1156. X}
  1157. X
  1158. XCatchSignalsPlease(action)
  1159. X#ifdef __TURBOC__
  1160. Xvoid (*action)();
  1161. X#else
  1162. Xint (*action)();
  1163. X#endif
  1164. X{
  1165. X   if( signal(SIGINT, SIG_IGN) != SIG_IGN ) signal(SIGINT, action);
  1166. X#ifndef MSDOS
  1167. X   if( signal(SIGQUIT, SIG_IGN) != SIG_IGN ) signal(SIGQUIT, action);
  1168. X   if( signal(SIGHUP, SIG_IGN) != SIG_IGN ) signal(SIGHUP, action);
  1169. X#endif
  1170. X}
  1171. X
  1172. XList()
  1173. X{
  1174. X   register int bp;
  1175. X   register char *bufp;
  1176. X   char buffer[MAXLINE];
  1177. X
  1178. X   NewFile(0);
  1179. X   bp = Braces = 0;
  1180. X   InString = InComment = 0; /* reset for new file -DV */
  1181. X
  1182. X   if (Language == C)
  1183. X      SawFunction = 0;
  1184. X   else if (Language == FORTRAN)
  1185. X      SawFunction = 1;  /* Put space after main program END card */
  1186. X   else if (Language == NONE)
  1187. X      Braces = 1;       /* Don't even call LooksLikeFunction */
  1188. X
  1189. X   bufp = buffer;
  1190. X   while( fgets(bufp, MAXLINE, File) != NULL )
  1191. X   {
  1192. X      ++FileLineNumber;
  1193. X      if( bp ) NewFunction();
  1194. X
  1195. X      if( ++LineNumber >= PageEnd ) NewPage();
  1196. X
  1197. X      if( bufp[0] == '\f'
  1198. X         && bufp[1] == '\n'
  1199. X         && bufp[2] == '\0' )
  1200. X      {
  1201. X     if( !IgnoreFF )
  1202. X        NewPage(); /* was strcpy(bufp, "^L\n");*/
  1203. X         continue;
  1204. X      }
  1205. X
  1206. X      if( (Braces == 0) && LooksLikeFunction(bufp) )
  1207. X         AddToTableOfContents(NEWFUNCTION);
  1208. X      else
  1209. X         PutString(buffer, -1, NumberFlag, 1);
  1210. X
  1211. X      if (Language != NONE)
  1212. X         bp = Scan(buffer);
  1213. X   }
  1214. X}
  1215. X
  1216. XScan(l)
  1217. Xregister char *l;
  1218. X{
  1219. X   extern char *EndComment();
  1220. X   extern char *EndString();
  1221. X   register char c;
  1222. X   int bp, offset;
  1223. X   char *save;
  1224. X
  1225. X   bp = 0;
  1226. X   switch (Language) {
  1227. X   case C:
  1228. X      for( save = l; c = *l; ++l )
  1229. X         if( InComment )
  1230. X            l = EndComment(l);
  1231. X         else if( InString )
  1232. X            l = EndString(l);
  1233. X         else
  1234. X            switch(c)
  1235. X            {
  1236. X            case '{':
  1237. X               ++Braces;
  1238. X               break;
  1239. X
  1240. X            case '}':
  1241. X               if( --Braces == 0 )
  1242. X                     bp = 1;
  1243. X               break;
  1244. X
  1245. X            case '\'':
  1246. X               for( ++l; *l && *l != '\''; ++l )
  1247. X                  if( *l == '\\' && *(l+1) ) ++l;
  1248. X               break;
  1249. X
  1250. X            case '"':
  1251. X               InString = 1;
  1252. X               break;
  1253. X
  1254. X            case '/':
  1255. X               if( *(l+1) == '*' )
  1256. X               {
  1257. X                  InComment = 1;
  1258. X                  ++l;
  1259. X               }
  1260. X               break;
  1261. X            }
  1262. X   break;
  1263. X   case FORTRAN:
  1264. X   /* Just check for an END card to indicate the routine is over... */
  1265. X      save = l;
  1266. X      while (isdigit(*l)) ++l;  /* Skip over any line statements. */
  1267. X      while (*l && (*l == ' ' || *l == '\t')) ++l;  /* Get to non-blank */
  1268. X   /* Icon really should only compare against lower case here. */
  1269. X      if (save != l && (offset = Compare (l, "END"))) {
  1270. X      /*
  1271. X         Check to make sure it isn't an ENDIF or some other variable name
  1272. X         (Unfortunately, build in a VMS ! comment checker here...)
  1273. X      */
  1274. X         l += offset;
  1275. X         if (*l == '\n' || *l == '!') {
  1276. X            Braces = 0;
  1277. X            bp = 1;
  1278. X         }
  1279. X      }
  1280. X   break;
  1281. X   case ICON:
  1282. X   /* Just check for an end keyword to indicate the routine is over... */
  1283. X      save = l;
  1284. X      while (*l && (*l == ' ' || *l == '\t')) ++l;  /* Get to non-blank */
  1285. X      if (l[0] == 'e' && l[1] == 'n' && l[2] == 'd') {
  1286. X      /*
  1287. X         Check to make sure it isn't an ENDIF or some other variable name
  1288. X      */
  1289. X         l += 3;
  1290. X         if (*l == '\n' || *l == '#') {
  1291. X            Braces = 0;
  1292. X            bp = 1;
  1293. X         }
  1294. X      }
  1295. X    break;
  1296. X    case LISP:
  1297. X    /*
  1298. X       Lisp requires the context to be preserved, hence Braces stays 0 (a
  1299. X       lie) and LooksLikeLisp() handles everything.
  1300. X    */
  1301. X    break;
  1302. X   }
  1303. X   return(bp);
  1304. X}
  1305. X
  1306. XPutString (str, len, line, newline)
  1307. Xchar *str;
  1308. Xint len;
  1309. Xint line;
  1310. Xint newline;
  1311. X{
  1312. X/*
  1313. X   All lines of program text that are written through here are checked for
  1314. X   tabs.  This should include all parts of each line of code (to keep the
  1315. X   internal column counter straight).
  1316. X*/
  1317. X   static char *lbuf = (char *)0;
  1318. X   static int   lbuflen = 0;
  1319. X   static char spaces[] = {"                                 "};
  1320. X   static int col = 0;
  1321. X   static int front=1;
  1322. X   int i, need;
  1323. X   register char *d, *s, c;
  1324. X
  1325. X   if (len == -1) len = strlen (str);
  1326. X
  1327. X   need =(len+OffsetValue+20)<<1;  /* mult by 2, so that \ work for postcript
  1328. X */
  1329. X   if( need > lbuflen ) {
  1330. X      if( lbuf ) free(lbuf);
  1331. X      lbuflen = need;
  1332. X      lbuf = (char *)malloc(lbuflen);
  1333. X      if( ! lbuf ) {
  1334. X     fprintf( stderr, "MALLOC error, insufficient memory\n" );
  1335. X     exit(1);
  1336. X      }
  1337. X   }
  1338. X   *lbuf = '\0';
  1339. X
  1340. X   if( OffsetValue && front ) sprintf (lbuf, "%.*s", OffsetValue, spaces);
  1341. X   if( line  && front ) {
  1342. X      sprintf (lbuf, "%6d  ", FileLineNumber);
  1343. X   }
  1344. X   front = 0;
  1345. X   col = strlen(lbuf);
  1346. X   d = lbuf+col;
  1347. X
  1348. X   s = str;
  1349. X   for (i=0; i < len; ++i, ++s) {
  1350. X      c = *s;
  1351. X      switch (c) {
  1352. X      case '\t':
  1353. X         do {
  1354. X        *d++ = ' ';
  1355. X         } while (col++ % TabWidth != (TabWidth - 1));
  1356. X      break;
  1357. X      case '\b':
  1358. X     *d++ = c;
  1359. X         if (col > 0) --col;
  1360. X      break;
  1361. X      case '\n':
  1362. X         col = 0;
  1363. X     if( s[1] ) *d++ = '\n';
  1364. X     break;
  1365. X      case '\f':
  1366. X         col = 0;
  1367. X     *d++ = c;
  1368. X      break;
  1369. X
  1370. X      case '(':
  1371. X      case ')':
  1372. X     if( Printer == POSTSCRIPT ) {
  1373. X        *d++ = '\\';
  1374. X        *d++ = c;
  1375. X        break;
  1376. X     }
  1377. X     /*FALLTHROUGH*/
  1378. X
  1379. X      default:
  1380. X     *d++ = c;
  1381. X         ++col;
  1382. X      }
  1383. X   }
  1384. X   *d++ = '\0';
  1385. X
  1386. X   switch(Printer) {
  1387. X      case POSTSCRIPT:
  1388. X         printf( "(%s) %s\n", lbuf, newline ? "s":"sn" );
  1389. X     break;
  1390. X
  1391. X      default:
  1392. X     printf( "%s", lbuf );
  1393. X     if(newline) putchar('\n');
  1394. X     break;
  1395. X   }
  1396. X   if( newline ) front = 1;
  1397. X}
  1398. X
  1399. XPutBold (bstr, len, flag)
  1400. Xchar *bstr;
  1401. Xint len, flag;
  1402. X/*-
  1403. X   Put ``str'' bolded on stdout (possibly using ^H's).  (This test a flag
  1404. X   to support other types of bolding options.)  Assume ``str'' is ``len''
  1405. X   characters long, unless ``len'' == -1, then use strlen for the length
  1406. X   of ``str''.  If ``flag'' is 0 then print here without calling PutString
  1407. X   (in other words, don't pass it on as part of a code line for tab
  1408. X   column counting/expansion).
  1409. X
  1410. X   When working with escape sequences, don't call PutString to print out the
  1411. X   escape sequences themselves.  Otherwise the tab expansion will be off.
  1412. X   (PutString adjusts column counter for \b's, but it doesn't need to know
  1413. X   about escape sequences.)
  1414. X*/
  1415. X{
  1416. X   int str_flag = 0;
  1417. X   char *str;
  1418. X
  1419. X   if( len == -1 ) {
  1420. X      len = strlen(bstr);
  1421. X      str = bstr;
  1422. X   }
  1423. X   else {
  1424. X      str_flag = 1;
  1425. X      str = malloc(len+2);
  1426. X      strncpy(str, bstr, len);
  1427. X   }
  1428. X
  1429. X   switch (Printer) {
  1430. X   case DUMB:
  1431. X      PutString (str, len, NumberFlag, 0);  /* Just give up--printer is too
  1432. X dumb */
  1433. X   break;
  1434. X   case ANSI:
  1435. X   case LN03:
  1436. X      printf ("\033[1m");
  1437. X      PutString (str, len, NumberFlag, 0);
  1438. X      printf ("\033[22m");
  1439. X   break;
  1440. X   case NECP5200:
  1441. X      printf ("\033E");
  1442. X      PutString (str, len, NumberFlag, 0);
  1443. X      printf ("\033F");
  1444. X   break;
  1445. X   case POSTSCRIPT:
  1446. X      printf( "(%s) sb\n", str );
  1447. X      break;
  1448. X
  1449. X   case BACKSPACE:
  1450. X   {
  1451. X      int j, k;
  1452. X      char *buf, *s;
  1453. X
  1454. X      s = buf = (char *)malloc(len*3+10);
  1455. X      for( k=0; *str; ) {
  1456. X     *s++ = *str;
  1457. X     *s++ = '\b';
  1458. X     *s++ = *str++;
  1459. X     k += 3;
  1460. X      }
  1461. X      *s++ = '\0';
  1462. X      /*
  1463. X      strcpy( s, str );
  1464. X      s += len;
  1465. X      for(k=0; k<len; k++ ) *s++='\b';
  1466. X      strcpy( s, str );
  1467. X      */
  1468. X
  1469. X      if (flag)
  1470. X         PutString (buf, k, NumberFlag, 0);
  1471. X      else
  1472. X         printf(buf);
  1473. X      free(buf);
  1474. X   }
  1475. X   break;
  1476. X
  1477. X   default:
  1478. X      fprintf (stderr, "Unknown printer type in PutBold\n");
  1479. X      exit (1);
  1480. X   }
  1481. X   if( str_flag ) free(str);
  1482. X}
  1483. X
  1484. Xchar *
  1485. XEndComment(p)
  1486. Xregister char *p;
  1487. X{
  1488. X   register char c;
  1489. X
  1490. X   /*
  1491. X         * Always return pointer to last non-null char looked at.
  1492. X         */
  1493. X   while( c = *p++ )
  1494. X      if( c == '*' && *p == '/' )
  1495. X      {
  1496. X         InComment = 0;
  1497. X         return(p);
  1498. X      }
  1499. X   return(p-2);
  1500. X}
  1501. X/* cpr got too big to ship as mail so I'm splitting it here... jdc */
  1502. X#include "cpr.c2"
  1503. END_OF_FILE
  1504. if test 27280 -ne `wc -c <'cpr.c'`; then
  1505.     echo shar: \"'cpr.c'\" unpacked with wrong size!
  1506. fi
  1507. # end of 'cpr.c'
  1508. fi
  1509. if test -f 'intro.doc' -a "${1}" != "-c" ; then 
  1510.   echo shar: Will not clobber existing file \"'intro.doc'\"
  1511. else
  1512. echo shar: Extracting \"'intro.doc'\" \(9883 characters\)
  1513. sed "s/^X//" >'intro.doc' <<'END_OF_FILE'
  1514. X
  1515. XGPLOTLIB Introduction
  1516. XBy John Campbell 3/90
  1517. X
  1518. XGPLOTLIB is an attempt to create a library of graphics routines out of the 
  1519. Xgnuplot package in order to gain access to all the terminal drivers that 
  1520. Xhave been written.  Note that gnuplot itself does not use these routines,
  1521. Xalthough the routines here have simply been extracted from the original
  1522. Xcode.  Unfortunately for maintainers, some of the routines had to be
  1523. Xchanged--generally simplified--in order to create a usable graphics plot
  1524. Xlibrary.  
  1525. X
  1526. XNote that an effort was made to avoid name space pollution.  This wasn't
  1527. Xnecessary in the original gnuplot code, but a library that is going to
  1528. Xpossibly be embedded in other packages should take some care regarding the
  1529. Xnames used by global symbols.  To this end, all globals begin with either
  1530. XGT or GSR and all external routine names begin with either ``gt_'' or
  1531. X``gsr_''.  Hence the routine ``test_term()'' from gnuplot/term.c becomes
  1532. X``gt_test_term()'' in gplotlib/gterm.c.  Many other internal routines 
  1533. Xwere made static to keep them from being external to the module.
  1534. X
  1535. XThe package itself consists of two 'C' modules and two header files:
  1536. Xgsr.h, gsr.c and gterm.c, gterm.h.  The latter pair directly use the
  1537. Xfiles in gnuplot/term and should be able to handle new terminal drivers
  1538. Xby changing gterm.c exactly as term.c had to be changed.  This is the 
  1539. Xlowest level of the library, providing direct access to the terminal 
  1540. Xdrivers using the external structure ``GTterm_tbl[]'' and the index 
  1541. X``GTterm''.
  1542. X
  1543. XIn order to use this lowest level of GPLOTLIB, you need to know how the 
  1544. Xterminal drivers of gnuplot function.  Russell Lang's README file from 
  1545. Xgnuplot/term is included below with some  slight modifications (such as 
  1546. Xchanging the names of global variables to more closely match those here 
  1547. Xin GPLOTLIB).
  1548. X
  1549. XThe other half of the package, gsr.h and gsr.c, provides the same sort of
  1550. Xgraphics support routines that gnuplot itself needed in the module 
  1551. Xgraphics.c.  Of course, gnuplot knew ahead of time what order it was
  1552. Xgoing to build it's plots and didn't need generic routines.  These gsr
  1553. Xroutines attempt to provide a "high-level" user coordinate based plotting 
  1554. Xpackage that allows users to easily do tasks similar to those that gnuplot 
  1555. Xdoes during interactive plotting.  
  1556. X
  1557. XNote that the documentation for all routines is derived directly out of 
  1558. Xthe 'C' code using a utility I wrote years ago called ``docu''.  Docu looks 
  1559. Xfor 'C' comments of the form /*- ... -*/ and extracts the text and any lines 
  1560. Xof code above the text to stdout.  Thus, only the items deemed of interest 
  1561. Xby the library writer are exported to the outside world.  The intent, of 
  1562. Xcourse, is that the documentation is accurate--at least the calling sequences 
  1563. Xshould be exact, as of the time the documentation was run off, because it 
  1564. Xshows the actual routine header.  Note also, that I filter the output of 
  1565. X``docu'' through another program called ``cpr''.   The version of ``cpr'' 
  1566. X(code printer) that I use is probably different than all but the most 
  1567. Xrecently submitted version from Dennis Vadura.
  1568. X
  1569. X
  1570. XDOCUMENTATION FOR GNUPLOT TERMINAL DRIVER WRITERS
  1571. XBy Russell Lang 1/90
  1572. X
  1573. XInformation on each terminal device driver is contained in term.c and
  1574. Xthe term/*.trm files.  Each driver is contained in a .trm file and is 
  1575. X#include'd into term.c.  Each driver has a set of initializers in 
  1576. Xgterm.c for GTterm_tbl[], an array of struct termentry.
  1577. X
  1578. XHere is the definition of the struct termentry from gtplot.h:
  1579. X
  1580. Xstruct termentry {
  1581. X    char *name;
  1582. X    char *description;
  1583. X    unsigned int xmax,ymax,v_char,h_char,v_tic,h_tic;
  1584. X    FUNC_PTR init,reset,text,scale,graphics,move,vector,linetype,
  1585. X        put_text,text_angle,justify_text,point,arrow;
  1586. X};
  1587. X
  1588. XHere's a brief description of each variable:
  1589. X
  1590. XThe char *name is a pointer to a string containing the name
  1591. Xof the terminal.  This name is used by the 'set terminal' and 
  1592. X'show terminal' commands.  
  1593. XThe name must be unique and must not be confused with an abbreviation 
  1594. Xof another name.  For example if the name "postscript" exists, it is not
  1595. Xpossible to have another name "postscript2".
  1596. XKeep the name under 15 characters.
  1597. X
  1598. XThe char *description is a pointer to a string containing a
  1599. Xdescription of the terminal, which is displayed in response
  1600. Xto the 'set terminal' command.  
  1601. XKeep the description under 60 characters.
  1602. X
  1603. Xxmax is the maximum number of points in the x direction.  
  1604. XThe range of points used by gnuplot is 0 to xmax-1.
  1605. X
  1606. Xymax is the maximum number of points in the y direction.  
  1607. XThe range of points used by gnuplot is 0 to ymax-1.
  1608. X
  1609. Xv_char is the height of characters, in the same units as xmax and ymax.
  1610. XThe border for labelling at the top and bottom of the plot is 
  1611. Xcalculated using v_char.  
  1612. Xv_char is used as the vertical line spacing for characters.
  1613. X
  1614. Xh_char is the width of characters, in the same units as xmax and ymax.
  1615. XThe border for labelling at the left and right of the plot is 
  1616. Xcalculated using h_char.  
  1617. XIf the _justify_text function returns FALSE, h_char is used to justify 
  1618. Xtext right or centre.  If characters are not fixed width, then the 
  1619. X_justify_text function must correctly justify the text.
  1620. X
  1621. Xv_tic is the vertical size of tics along the x axis, 
  1622. Xin the same units as ymax.
  1623. X
  1624. Xh_tic is the horizontal size of tics along the y axis, 
  1625. Xin the same units as xmax.
  1626. X
  1627. X
  1628. XHere's a brief description of what each term.c function does:
  1629. X
  1630. X_init()  Called once, when the device is first selected.  This procedure
  1631. Xshould set up things that only need to be set once, like handshaking and
  1632. Xcharacter sets etc...
  1633. X
  1634. X_reset()  Called when gnuplot is exited, the output device changed or
  1635. Xthe terminal type changed.  This procedure should reset the device, 
  1636. Xpossibly flushing a buffer somewhere or generating a form feed.
  1637. X
  1638. X_scale(xs,ys) Called just before _graphics(). This takes the x and y
  1639. Xscaling factors as information. If the terminal would like to do its
  1640. Xown scaling, it returns TRUE. Otherwise, it can ignore the information
  1641. Xand return FALSE: GSR routines can do the scaling for you. null_scale is
  1642. Xprovided to do just this, so most drivers can ignore this function
  1643. Xentirely. The Latex driver is currently the only one providing its own
  1644. Xscaling.
  1645. X
  1646. X_graphics()  Called just before a plot is going to be displayed.  This
  1647. Xprocedure should set the device into graphics mode.  Devices which can't
  1648. Xbe used as terminals (like plotters) will probably be in graphics mode 
  1649. Xalways.
  1650. X
  1651. X_text()  Called immediately after a plot is displayed.  This procedure 
  1652. Xshould set the device back into text mode if it is also a terminal, so
  1653. Xthat commands can be seen as they're typed.  Again, this will probably
  1654. Xdo nothing if the device can't be used as a terminal.
  1655. X
  1656. X_move(x,y)  Called at the start of a line.  The cursor should move to the
  1657. X(x,y) position without drawing.
  1658. X
  1659. X_vector(x,y)  Called when a line is to be drawn.  This should display a line
  1660. Xfrom the last (x,y) position given by _move() or _vector() to this new (x,y)
  1661. Xposition.
  1662. X
  1663. X_linetype(lt)  Called to set the line type before text is displayed or
  1664. Xline(s) plotted.  This procedure should select a pen color or line
  1665. Xstyle if the device has these capabilities.  
  1666. Xlt is an integer from -2 to 0 or greater.  
  1667. XAn lt of -2 is used for the border of the plot.
  1668. XAn lt of -1 is used for the X and Y axes.  
  1669. Xlt 0 and upwards are used for plots 0 and upwards.
  1670. XIf _linetype() is called with lt greater than the available line types, 
  1671. Xit should map it to one of the available line types.
  1672. XMost drivers provide 9 different linetypes (lt is 0 to 8).
  1673. X
  1674. X_put_text(x,y,str)  Called to display text at the (x,y) position, 
  1675. Xwhile in graphics mode.   The text should be vertically (with respect 
  1676. Xto the text) justified about (x,y).  The text is rotated according 
  1677. Xto _text_angle and then horizontally (with respect to the text)
  1678. Xjustified according to _justify_text.
  1679. X
  1680. X_text_angle(ang)  Called to rotate the text angle when placing the y label.
  1681. XIf ang = 0 then text is horizontal.  If ang = 1 then text is vertically
  1682. Xupwards.  Returns TRUE if text can be rotated, FALSE otherwise.
  1683. X
  1684. X_justify_text(mode)  Called to justify text left, right or centre.
  1685. XIf mode = LEFT then text placed by _put_text is flushed left against (x,y).
  1686. XIf mode = CENTRE then centre of text is at (x,y).  
  1687. XIf mode = RIGHT then text is placed flushed right against (x,y).
  1688. XReturns TRUE if text can be justified
  1689. XReturns FALSE otherwise and then _put_text assumes text is flushed left;
  1690. Xjustification of text is then performed by calculating the text width
  1691. Xusing strlen(text) * h_char.
  1692. X
  1693. X_point(x,y,point)  Called to place a point at position (x,y).
  1694. Xpoint is -1 or an integer from 0 upwards.  
  1695. X6 point types (numbered 0 to 5) are normally provided.  
  1696. XPoint type -1 is a dot.
  1697. XIf point is more than the available point types then it should 
  1698. Xbe mapped back to one of the available points.
  1699. XTwo _point() functions called do_point() and line_and_point() are 
  1700. Xprovided in term.c and should be suitable for most drivers.  
  1701. Xdo_point() draws the points in the current line type.
  1702. XIf your driver uses dotted line types (generally because it is
  1703. Xmonochrome), you should use line_and_point() which changes to 
  1704. Xline type 0 before drawing the point.  line type 0 should be solid.
  1705. X
  1706. X
  1707. X_arrow(sx,sy,ex,ey)  Called to draw an arrrow from (sx,sy) to (ex,ey).
  1708. XAn _arrow() function called do_arrow() is provided in term.c which will
  1709. Xdraw arrows using the _move() and _vector() functions.  
  1710. XDrivers should use do_arrow unless it causes problems.
  1711. X
  1712. X
  1713. XThe following should illustrate the order in which calls to these
  1714. Xroutines are made:
  1715. X
  1716. X  _init()
  1717. X    _scale(xs,ys)
  1718. X    _graphics()
  1719. X      _linetype(lt)
  1720. X      _move(x,y)
  1721. X      _vector(x,y)
  1722. X      _point(x,y,point)
  1723. X      _text_angle(angle)
  1724. X      _justify(mode)
  1725. X      _put_text(x,y,text)
  1726. X      _arrow(sx,sy,ex,ey)
  1727. X    _text()
  1728. X    _graphics()
  1729. X      .
  1730. X      .
  1731. X    _text()
  1732. X  _reset()
  1733. X
  1734. X[And, of course, gt_test_term() in gterm.c is a real live example of
  1735. X calling some of these routines. JDC]
  1736. END_OF_FILE
  1737. if test 9883 -ne `wc -c <'intro.doc'`; then
  1738.     echo shar: \"'intro.doc'\" unpacked with wrong size!
  1739. fi
  1740. # end of 'intro.doc'
  1741. fi
  1742. echo shar: End of archive 2 \(of 5\).
  1743. cp /dev/null ark2isdone
  1744. MISSING=""
  1745. for I in 1 2 3 4 5 ; do
  1746.     if test ! -f ark${I}isdone ; then
  1747.     MISSING="${MISSING} ${I}"
  1748.     fi
  1749. done
  1750. if test "${MISSING}" = "" ; then
  1751.     echo You have unpacked all 5 archives.
  1752.     rm -f ark[1-9]isdone
  1753. else
  1754.     echo You still need to unpack the following archives:
  1755.     echo "        " ${MISSING}
  1756. fi
  1757. ##  End of shell archive.
  1758. exit 0
  1759.  
  1760.